﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utiles.Excepcion;
using Utiles.Persistencia;
using System.Windows.Forms;

namespace EntidadesDeNegocio
{
    public class Stock:ObjetoPersistente
    {
        /// <summary>
        /// Instancia privada de singleton
        /// </summary>
        private static Stock _Instancia;
        /// <summary>
        /// Objecto para realizar lockeo del hilo
        /// </summary>
        private static object Lockea = new object();
        #region Singleton
        /// <summary>
        /// Instancia de clase (singleton)
        /// </summary>
        public static Stock Instancia 
        {
            get 
            {
                if (_Instancia == null)
                {
                    lock (Lockea)
                    {
                        if (_Instancia == null)
                            _Instancia = new Stock();                        
                    }
                }
                return _Instancia;
            }
        }
        #endregion
        /// <summary>
        /// Constructor sin parametros privado para no permitir que se creen instancias del mismo.
        /// </summary>
        private Stock() 
        {
            ListaComponentes = new List<Componente>();
        }
        /// <summary>
        /// Lista de componentes del stock
        /// </summary>
        public List<Componente> ListaComponentes
        {
            get
            {
                return this.MostrarTodoBD().Cast<Componente>().ToList();
            }
            set{}
        }
        /// <summary>
        /// Agrega componente al stock
        /// </summary>
        /// <param name="componente"></param>
        public void AgregarComponente(string modelo, string numeroSerie, MedioComponente medio, decimal costo, string descripcion, DateTime fechaCreacion, int cantidad, DateTime fechaService,bool esRobot,decimal temperatura,decimal profundidad,decimal altitud,decimal velocidad,List<Componente> listComp) 
        {
            Componente comp = null;
            if (!esRobot)
            {
                switch (medio)
                {
                    case MedioComponente.Acuatico:
                        comp = new PiezaAcuatica(modelo, numeroSerie, medio, costo, descripcion, fechaCreacion, cantidad, fechaService,profundidad);
                        break;
                    case MedioComponente.Aereo:
                        comp = new PiezaAerea(modelo, numeroSerie, medio, costo, descripcion, fechaCreacion, cantidad, fechaService, altitud,velocidad);
                        break;
                    case MedioComponente.Terrestre:
                        comp = new PiezaTerrestre(modelo, numeroSerie, medio, costo, descripcion, fechaCreacion, cantidad, fechaService,temperatura);
                        break;
                    default:
                        break;
                }
            }
            else 
            {
                comp = new Robot(modelo, numeroSerie, medio, costo, descripcion, fechaCreacion, cantidad, fechaService,listComp);
            }
            try 
            {
                comp.AgregarBD();                
            }
            catch (BDExcepcion ex)
            {
                MessageBox.Show("Error al guardar Componente en la base de datos - Mensaje: " + ex.Message);
            }
            
        }
        /// <summary>
        /// Elimina el componente del stock
        /// </summary>
        /// <param name="componente"></param>
        public void EliminarComponente(string modelo) 
        {
            Componente comp = ObtenerComponente(modelo);
            try
            {
                comp.EliminarBD();
            }
            catch (BDExcepcion ex)
            {
                MessageBox.Show("Error al eliminar Componente en la base de datos - Mesaje: " + ex.Message);
            }
            
        }
        /// <summary>
        /// Modifica un componente
        /// </summary>
        /// <param name="componente"></param>
        public void ModificarComponente(string modelo, string numeroSerie, MedioComponente medio, decimal costo, string descripcion, DateTime fechaCreacion, int cantidad, DateTime fechaService, bool esRobot, decimal temperatura, decimal profundidad,decimal altitud,decimal velocidad)
        {
            Componente com = ObtenerComponente(modelo);            
            com.Costo = costo;
            com.FechaCreacion = fechaCreacion;
            com.Descripcion = descripcion;            
            com.Cantidad = cantidad;
            com.FechaService = fechaService;
            switch (medio)
            {
                case MedioComponente.Acuatico:
                    if(!esRobot)
                        ((PiezaAcuatica)com).Profundidad = profundidad;
                    break;
                case MedioComponente.Terrestre:
                    if (!esRobot)
                        ((PiezaTerrestre)com).Temperatura = temperatura;
                    break;
                case MedioComponente.Aereo:
                    if (!esRobot)
                    {
                        ((PiezaAerea)com).Altitud = altitud;
                        ((PiezaAerea)com).Velocidad = velocidad;
                    }                        
                    break;
                default:
                    break;
            }
            try
            {
                com.ModificarBD();
            }
            catch (BDExcepcion ex)
            {
                MessageBox.Show("Error al modificar Componente en la base de datos - Mesaje: " + ex.Message);
            }
        }
        /// <summary>
        /// Retorna el compononete con el modelo elegido
        /// </summary>
        /// <param name="componente"></param>
        /// <returns></returns>
        public Componente ObtenerComponente(string modelo) 
        {
            Componente comp = null;
            if (ListaComponentes.Count() != 0)
            {
                try
                {
                    comp = (from Componente c in ListaComponentes where c.Modelo.ToLower() == modelo.ToLower() select c).First();                    
                }
                catch { }
            }
            return comp;
        }
        /// <summary>
        /// Chequea que exista el numero de serie ingresado
        /// </summary>
        /// <param name="numeroSerie"></param>
        /// <returns></returns>
        public bool ExisteNumeroDeSerie(string numeroSerie) 
        {
            bool resultado = false;
            foreach (Componente c in ListaComponentes)
            {
                if (c.NumeroSerie.ToLower() == numeroSerie.ToLower())
                    return true;               
            }            
            return resultado;
        }
        /// <summary>
        /// Chequea que exista el modelo ingresado
        /// </summary>
        /// <param name="modelo"></param>
        /// <returns></returns>
        public bool ExisteModelo(string modelo)
        {
            bool resultado = false;
            foreach (Componente c in ListaComponentes)
            {
                if (c.Modelo.ToLower() == modelo.ToLower())
                    return true;
            }
            return resultado;
        }
        /// <summary>
        /// Retorna la lista de componentes ordenada por modelo y fechacreacion
        /// </summary>
        /// <returns></returns>
        public List<Componente> ListaComponentesOrdenada() 
        {
            List<Componente> list = (from Componente c in ListaComponentes
                                     orderby c.Modelo ascending, c.FechaCreacion ascending
                                     select c).ToList();
            return list;
        }
        /// <summary>
        /// Devuelvo solo la lista de robots
        /// </summary>
        /// <returns></returns>
        public List<Componente> ListaRobots()
        {
            List<Componente> listaAux = new List<Componente>();
            listaAux = (from Componente c in ListaComponentes
                        where c.GetTipo() == TipoComponente.Robot
                        select c).ToList();
            return listaAux;
        }
    }
}
